package com.zoro.barn.business.service.sqldocument.business.sql.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.zoro.barn.commons.db.autopage.PageList;
import com.zoro.barn.business.service.sqldocument.business.sql.dto.MoveOneSqlDto;
import com.zoro.barn.business.service.sqldocument.business.sql.dto.SqlInfoDto;
import com.zoro.barn.business.service.sqldocument.business.sql.dto.UseProjectDto;
import com.zoro.barn.business.service.sqldocument.business.sql.entity.BarnSqlInfo;
import com.zoro.barn.business.service.sqldocument.business.sql.entity.BarnSqlUsage;
import com.zoro.barn.business.service.sqldocument.business.sql.service.BarnSqlInfoService;
import com.zoro.barn.business.service.sqldocument.server.facade.BarnProductServerFacade;
import com.zoro.barn.business.service.sqldocument.server.facade.BarnUserServerFacade;
import com.zoro.barn.commons.tools.json.JsonUtil;
import com.zoro.barn.commons.webcommons.tools.RequestUser;
import com.zoro.barn.commons.webcommons.tools.WebContentUtil;
import com.zoro.barn.dto.system.BarnUserInfoDto;
import com.zoro.barn.dto.pp.product.BarnProductInfoDto;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author zhaoxingwu
 */
@RestController
@RequestMapping("/sql")
public class BarnSqlInfoController {

    private final BarnSqlInfoService barnSqlInfoService;
    private final BarnProductServerFacade barnProductProjectServerFacade;
    private final BarnUserServerFacade barnUserServer;

    public BarnSqlInfoController(BarnSqlInfoService barnSqlInfoService, BarnProductServerFacade barnProductProjectServerFacade,
                                 BarnUserServerFacade barnUserServer) {
        this.barnSqlInfoService = barnSqlInfoService;
        this.barnProductProjectServerFacade = barnProductProjectServerFacade;
        this.barnUserServer = barnUserServer;
    }

    /**
     * only query sql those create by login people
     *
     * @param info query parameters
     * @return result
     * @throws Exception e
     */
    @RequestMapping("/queryMySql")
    public List<SqlInfoDto> queryMySql(BarnSqlInfo info) throws Exception {
        String userId = WebContentUtil.requestUserInfo().getPid();
        info.setCreateId(userId);
        return query(info);
    }

    /**
     * query all sql
     *
     * @param info query parameters
     * @return result
     */
    @RequestMapping("/queryAll")
    public List<SqlInfoDto> queryAll(BarnSqlInfo info) throws Exception {
        return query(info);
    }

    private List<SqlInfoDto> query(BarnSqlInfo info) throws Exception {
        List<BarnSqlInfo> sqlInfos = barnSqlInfoService.query(info);
        List<SqlInfoDto> result = PageList.fromCollection(sqlInfos, SqlInfoDto.class);
        if (CollectionUtils.isNotEmpty(sqlInfos) && CollectionUtils.isNotEmpty(result)) {
            // query product name
            Set<String> productIds = sqlInfos.stream().map(BarnSqlInfo::getProductId).collect(Collectors.toSet());
            Map<String, BarnProductInfoDto> resultMap = this.barnProductProjectServerFacade.getProductMap(productIds.toArray(new String[1]));
            if (resultMap != null) {
                result.forEach(v -> {
                    BarnProductInfoDto dto = resultMap.get(v.getProductId());
                    if (dto != null) {
                        v.setProductName(dto.getProductName());
                    }
                });
            }

            // query create-people name
            Set<String> userIds = sqlInfos.stream().map(BarnSqlInfo::getCreateId).collect(Collectors.toSet());
            List<BarnUserInfoDto> users = this.barnUserServer.getUserInfos(userIds.toArray(new String[1]));
            if (CollectionUtils.isNotEmpty(users)) {
                Map<String, String> userNameMap = users.stream().collect(Collectors.toMap(BarnUserInfoDto::getPid, BarnUserInfoDto::getUserName, (a, b) -> b));
                result.forEach(v -> {
                    String name = userNameMap.get(v.getCreateId());
                    v.setCreateName(name);
                });
            }
        }

        return result;
    }

    @RequestMapping("/save")
    public BarnSqlInfo save(@RequestBody SqlInfoDto param) throws JsonProcessingException {

        String userId = WebContentUtil.requestUserInfo().getPid();
        BarnSqlInfo sqlInfo = JsonUtil.transformType(param, BarnSqlInfo.class);
        List<UseProjectDto> use = param.getUse();
        List<BarnSqlUsage> usages = null;
        if (CollectionUtils.isNotEmpty(use)) {
            usages = use.stream().map(v -> {
                BarnSqlUsage e = new BarnSqlUsage();
                e.setProjectId(v.getPid());
                e.setProjectName(v.getProjectName());
                return e;
            }).collect(Collectors.toList());
        }
        if (StringUtils.isBlank(sqlInfo.getPid())) {
            // Insert
            sqlInfo.setCreateId(userId);
            return this.barnSqlInfoService.insert(sqlInfo, param.getSqlText(), usages);
        } else {
            // Update
            sqlInfo.setUpdateId(userId);
            return this.barnSqlInfoService.update(sqlInfo, param.getSqlText(), usages);
        }
    }

    @RequestMapping("/deleteById")
    public void deleteById(@RequestBody BarnSqlInfo info) {
        this.barnSqlInfoService.deleteById(info.getPid());
    }

    @RequestMapping("/getById/{pid}")
    public SqlInfoDto getById(@PathVariable("pid") String pid) throws Exception {
        if (StringUtils.isBlank(pid)) {
            return null;
        }
        BarnSqlInfo info = this.barnSqlInfoService.getById(pid);
        if (info == null) {
            return null;
        }

        SqlInfoDto dto = JsonUtil.transformType(info, SqlInfoDto.class);
        String sqlText = this.barnSqlInfoService.getSqlText(info.getDocumentId());
        dto.setSqlText(sqlText);

        List<BarnSqlUsage> use = this.barnSqlInfoService.getUseBySqlId(info.getPid());
        if (CollectionUtils.isNotEmpty(use)) {
            List<UseProjectDto> u = use.stream().map(v -> {
                UseProjectDto e = new UseProjectDto();
                e.setPid(v.getProjectId());
                e.setProjectName(v.getProjectName());
                return e;
            }).collect(Collectors.toList());
            dto.setUse(u);
        }

        // 创建人
        if (StringUtils.isNotBlank(info.getCreateId())) {
            List<BarnUserInfoDto> users = this.barnUserServer.getUserInfos(new String[]{info.getCreateId()});
            if (CollectionUtils.isNotEmpty(users)) {
                dto.setCreateName(users.get(0).getUserName());
            }
        }

        // 产品名
        if (StringUtils.isNotBlank(info.getProductId())) {
            Map<String, BarnProductInfoDto> result = this.barnProductProjectServerFacade.getProductMap(new String[]{info.getProductId()});
            if (result != null) {
                BarnProductInfoDto productInfoDto = result.get(info.getProductId());
                if (productInfoDto != null) {
                    dto.setProductName(productInfoDto.getProductName());
                }
            }
        }
        return dto;
    }

    /**
     * 移动单条sql到指定位置
     *
     * @param moveOneSqlDto param
     */
    @RequestMapping("/moveOneSql")
    public void moveOneSql(@RequestBody MoveOneSqlDto moveOneSqlDto) throws JsonProcessingException {

        String from = moveOneSqlDto.getFrom();
        String to = moveOneSqlDto.getTo();
        RequestUser user = WebContentUtil.requestUserInfo();
        this.barnSqlInfoService.moveSingleSql(from, to, user.getUserName(), user.getAccount());
    }
    // todo-future  批量移动sql

}
